/* Turska Framework/UI library (Turs2)
 * Copyright 2003-2008 Jetro Lauha
 * All rights reserved.
 * Web: http://iki.fi/jetro/turska/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of EITHER:
 *   (1) The GNU Lesser General Public License as published by the Free
 *       Software Foundation; either version 2.1 of the License, or (at
 *       your option) any later version. The text of the GNU Lesser
 *       General Public License is included with this library in the
 *       file LICENSE-LGPL.txt.
 *   (2) The BSD-style license that is included with this library in
 *       the file LICENSE-BSD.txt.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
 *
 * $Id: MainState.cpp 132 2009-06-05 06:09:16Z jlauha $
 * $Revision: 132 $
 */

#include <assert.h>
#include <math.h>

#include "main.h"

#include "MainState.h"


MainState::MainState()
{
    mHorizSliderValue = 0;
    mVertSliderValue = 0;
    mCheckboxValue = true;
}


MainState::~MainState()
{
}


bool MainState::init()
{
    Graphics *g = App::getInstance()->getGraphics();

    //mFont = new VerticalStripBitmapFontSDLOpenGL(static_cast<GraphicsSDLOpenGL *>(g), "data/font-vstrip-treb-outline.png");
    mFont = new BMFont(g, "data/droid30.fnt");
    if (!mFont->init())
        return false;
    // the example font has black outline, so we tweak
    // character spacing so that outlines of nearby glyphs overlap
    //mFont->setCharacterSpacing(-1);

    // Make sure these are in synch with IMAGE_ID
    mImages.push_back(g->loadImage("data/button.png"));
    mImages.push_back(g->loadImage("data/button-hot.png"));
    mImages.push_back(g->loadImage("data/button-active.png"));
    mImages.push_back(g->loadImage("data/button-hot-active.png"));
    mImages.push_back(g->loadImage("data/slider.png"));
    mImages.push_back(g->loadImage("data/slider-hot.png"));
    mImages.push_back(g->loadImage("data/slider-active.png"));
    mImages.push_back(g->loadImage("data/slider-hot-active.png"));
    mImages.push_back(g->loadImage("data/slider-thumb.png"));
    mImages.push_back(g->loadImage("data/slider-thumb-hot.png"));
    mImages.push_back(g->loadImage("data/slider-thumb-active.png"));
    mImages.push_back(g->loadImage("data/slider-thumb-hot-active.png"));
    mImages.push_back(g->loadImage("data/vslider.png"));
    mImages.push_back(g->loadImage("data/vslider-hot.png"));
    mImages.push_back(g->loadImage("data/vslider-active.png"));
    mImages.push_back(g->loadImage("data/vslider-hot-active.png"));
    mImages.push_back(g->loadImage("data/vslider-thumb.png"));
    mImages.push_back(g->loadImage("data/vslider-thumb-hot.png"));
    mImages.push_back(g->loadImage("data/vslider-thumb-active.png"));
    mImages.push_back(g->loadImage("data/vslider-thumb-hot-active.png"));
    mImages.push_back(g->loadImage("data/textfield.png"));
    mImages.push_back(g->loadImage("data/textfield-hot.png"));
    mImages.push_back(g->loadImage("data/textfield-active.png"));
    mImages.push_back(g->loadImage("data/textfield-caret.png"));
    mImages.push_back(g->loadImage("data/checkbox.png"));
    mImages.push_back(g->loadImage("data/checkbox-hot.png"));
    mImages.push_back(g->loadImage("data/checkbox-active.png"));
    mImages.push_back(g->loadImage("data/checkbox-hot-active.png"));
    mImages.push_back(g->loadImage("data/checkbox-check.png"));

    mButtonStyle = new IMGUIImageButtonStyle(mFont, mImages[IMG_BUTTON], mImages[IMG_BUTTON_HOT], mImages[IMG_BUTTON_ACTIVE], mImages[IMG_BUTTON_HOT_ACTIVE]);
    mHorizSliderStyle = new IMGUIImageSliderStyle(mImages[IMG_HSLIDER], mImages[IMG_HSLIDER_HOT],
                                                  mImages[IMG_HSLIDER_ACTIVE], mImages[IMG_HSLIDER_HOT_ACTIVE],
                                                  mImages[IMG_HSLIDER_THUMB], mImages[IMG_HSLIDER_THUMB_HOT],
                                                  mImages[IMG_HSLIDER_THUMB_ACTIVE], mImages[IMG_HSLIDER_THUMB_HOT_ACTIVE]);
    mVertSliderStyle = new IMGUIImageSliderStyle(mImages[IMG_VSLIDER], mImages[IMG_VSLIDER_HOT],
                                                 mImages[IMG_VSLIDER_ACTIVE], mImages[IMG_VSLIDER_HOT_ACTIVE],
                                                 mImages[IMG_VSLIDER_THUMB], mImages[IMG_VSLIDER_THUMB_HOT],
                                                 mImages[IMG_VSLIDER_THUMB_ACTIVE], mImages[IMG_VSLIDER_THUMB_HOT_ACTIVE]);
    mTextFieldStyle = new IMGUIImageTextFieldStyle(mFont, mImages[IMG_TEXTFIELD_CARET], mImages[IMG_TEXTFIELD], mImages[IMG_TEXTFIELD_HOT], mImages[IMG_TEXTFIELD_ACTIVE]);
    mCheckboxStyle = new IMGUIImageButtonStyle(mFont, mImages[IMG_CHECKBOX], mImages[IMG_CHECKBOX_HOT], mImages[IMG_CHECKBOX_ACTIVE], mImages[IMG_CHECKBOX_HOT_ACTIVE]);

    mLabelText = "";

    return mFont != NULL && mButtonStyle != NULL;
}


void MainState::deinit()
{
    UI32 a;
    delete mCheckboxStyle;
    delete mTextFieldStyle;
    delete mVertSliderStyle;
    delete mHorizSliderStyle;
    delete mButtonStyle;
    for (a = 0; a < mImages.size(); ++a)
        delete mImages[a];
    mImages.clear();
    delete mFont;
}


void MainState::onActivate(UI32 time)
{
    AppState::onActivate(time);
    mStartTime = 0; // first call to update will do actual initialization
    mPaused = false;
}


bool MainState::onKeyUp(const SDL_keysym & /*event*/)
{
    return false;
}

bool MainState::onKeyDown(const SDL_keysym &event)
{
    KeyEvent ke;

    ke.action = KA_NONE;
    if (event.sym == SDLK_TAB)
    {
        if (event.mod & KMOD_SHIFT)
            ke.action = KA_PREVIOUS;
        else
            ke.action = KA_NEXT;
    }
    else if (event.sym == SDLK_RETURN || event.sym == SDLK_KP_ENTER)
        ke.action = KA_SELECT;
    else if (event.sym == SDLK_LEFT || (event.sym == SDLK_KP4 && event.unicode != '4'))
        ke.action = KA_LEFT;
    else if (event.sym == SDLK_RIGHT || (event.sym == SDLK_KP6 && event.unicode != '6'))
        ke.action = KA_RIGHT;
    else if (event.sym == SDLK_UP || (event.sym == SDLK_KP8 && event.unicode != '8'))
        ke.action = KA_UP;
    else if (event.sym == SDLK_DOWN || (event.sym == SDLK_KP2 && event.unicode != '2'))
        ke.action = KA_DOWN;
    else
        ke.action = KA_CHAR;
    ke.character = event.unicode;
    ke.shift = (event.mod & KMOD_SHIFT) ? true : false;
    ke.control = (event.mod & KMOD_CTRL) ? true : false;
    ke.alt = (event.mod & KMOD_ALT) ? true : false;
    ke.platformEvent = &event;

    mIMGUI.onKeyDown(ke);

    if (event.sym == SDLK_ESCAPE)
        App::getInstance()->setAlive(false);

    return false; // should probably get this from onKeyDown?
}

bool MainState::onMouseDown(const SDL_MouseButtonEvent & /*event*/)
{
    mIMGUI.onMouseDown();
    return false;
}

bool MainState::onMouseUp(const SDL_MouseButtonEvent & /*event*/)
{
    mIMGUI.onMouseUp();
    return false;
}

bool MainState::onMouseMotion(const SDL_MouseMotionEvent &event)
{
    mIMGUI.onMouseMotion(event.x, event.y);
    return false;
}

bool MainState::onMouseWheel(I32 /*direction*/)
{
    return false;
}


bool MainState::update(UI32 time)
{
    bool result = AppState::update(time);
    if (!result)
        return false; // game is paused...

    // Following is executed only when game is not paused.

    //
    // TODO - Add game logic & physics update here.
    //

    return true;
}


void MainState::render(SDL_Surface *screen)
{
    assert(screen);

    glClearColor(0.2f, 0.267f, 0.333f, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    Graphics *g = App::getInstance()->getGraphics();
    g->beginRender();
    mIMGUI.begin(mTime);

#if 0
    turska::Rectangle r((REAL)(mImages[IMG_BUTTON]->getOriginalWidth() - 30),
                        (REAL)(mImages[IMG_BUTTON]->getOriginalHeight() - 30),
                        20, 20);
    Image *img = mImages[IMG_BUTTON];
    img->setSourceRectangle(&r);
    img->setPivot(10, 10);
    img->setTargetSize(100 + (float)sin(mTime * 0.01) * 20, 10.f);
    img->draw(IDM_NORMAL, /*IF_TRANSFORM |*/ IF_ALIGN_CENTER, 10, 10);
    img->setSourceRectangle(0);
    img->resetTargetSize();
    img->resetPivot();
#endif
    //img->draw(IDM_NORMAL, /*IF_TRANSFORM |*/ IF_ALIGN_CENTER, 10, 40);
    //mImages[IMG_BUTTON]->setTargetSize(20, 20);
    //mImages[IMG_BUTTON]->draw(IDM_NORMAL, IF_TRANSFORM, 10, 10, &r);

    if (mIMGUI.button(100, 50, IMGUI_AI_COUNTER, mButtonStyle, 0, 0, "Button A"))
        mLabelText = "Button A pressed";
    if (mIMGUI.button(100, 150, IMGUI_AI_COUNTER, mButtonStyle, 0, 0, "Button B"))
        mLabelText = "Button B pressed";
    if (mIMGUI.checkBox(100, 250, mCheckboxValue, IMGUI_AI_COUNTER, mCheckboxStyle, 0, 0, 0, mImages[IMG_CHECKBOX_CHECK]))
        mLabelText = mCheckboxValue ? "Checkbox checked" : "Checkbox unchecked";
    mFont->drawString(120, 250, "Checkbox", IF_ALIGN_TOP_LEFT, 0.5f);

    char buf[100];
    mIMGUI.slider(100, 350, mHorizSliderValue, IMGUI_AI_COUNTER, IMGUI_WO_HORIZONTAL, mHorizSliderStyle, 0, 100, 1);
    sprintf(buf, "%d", mHorizSliderValue);

    const I32 textMaxLen = 10;
    static C8 text[textMaxLen + 1] = { 0 };
    mIMGUI.textField(300, 50, text, textMaxLen, IMGUI_AI_COUNTER, mTextFieldStyle);

    mFont->drawString(250, 350, buf);
    mIMGUI.slider(400, 300, mVertSliderValue, IMGUI_AI_COUNTER, IMGUI_WO_VERTICAL, mVertSliderStyle, 0, 1, 0.01f);
    sprintf(buf, "%.2f", mVertSliderValue);
    mFont->drawString(450, 350, buf);

    if (mIMGUI.button(0, 0, IMGUI_AI_COUNTER, 0, (REAL)screen->w, (REAL)screen->h))
        mIMGUI.setActiveKeyWidgetId(mIMGUI.getAutoIdCounter());

    /*
    // simple rotation test
    mImages[IMG_HSLIDER]->setTargetSize(100, 100);
    mImages[IMG_HSLIDER]->setScale(1, 5);
    mImages[IMG_HSLIDER]->setAngle(mTime * 0.001f);
    mImages[IMG_HSLIDER]->draw(IDM_NORMAL, IF_FLIP_VERT | IF_ALIGN_TOP_LEFT | IF_TRANSFORM | IF_SCALE | IF_ROTATE,
        App::getInstance()->getScreenWidth() - 100, App::getInstance()->getScreenHeight() - 100);
    */

    /*
    // mipmaptest
    F32 scale = mTime * 0.0001f;
    if (scale > 1) scale = 1;
    mImages[0]->setScale(scale);
    mImages[0]->draw(IDM_NORMAL, IF_TRANSFORM|IF_SCALE, 0, 0);
    */

    mFont->drawString(300, 200, mLabelText);

    mIMGUI.end();
    g->endRender();
}
